package com.ssy.lingxi.report.serviceimpl.tally;

import com.ssy.lingxi.report.api.enums.LogisticsOperateTypeEnum;
import com.ssy.lingxi.report.api.enums.OperateDataSourceEnum;
import com.ssy.lingxi.report.api.vo.request.OperateNoticeVO;
import com.ssy.lingxi.report.dao.logistics.LogisticsOrderDAO;
import com.ssy.lingxi.report.entity.report.MemberTallyReportDO;
import com.ssy.lingxi.report.model.bo.MemberTallyReportBO;
import com.ssy.lingxi.report.model.bo.StatisticsCountBO;
import com.ssy.lingxi.report.model.bo.tally.LogisticsTallyBO;
import com.ssy.lingxi.report.model.constant.logistics.LogisticsOrderStatusEnum;
import com.ssy.lingxi.report.model.vo.response.LogisticsTallyReportVO;
import com.ssy.lingxi.report.service.tally.ILogisticsTallyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 物流计数统计接口实现
 * @author 伍将
 * @date 2020/11/23
 * @version 2.0.0
 */
@Service
public class LogisticsTallyServiceImpl implements ILogisticsTallyService {

    private static final Logger logger = LoggerFactory.getLogger(LogisticsTallyServiceImpl.class);

    @Autowired
    private LogisticsOrderDAO logisticsOrderDAO;

    /**
     * 转换物流
     * @param reportBO
     * @return
     */
    @Override
    public LogisticsTallyReportVO convertLogistics(LogisticsTallyBO reportBO) {
        LogisticsTallyReportVO result = new LogisticsTallyReportVO();
        if (reportBO == null) {
            reportBO = new LogisticsTallyBO();
        }
        result.setToBeConfirmCount(reportBO.getToBeConfirmCount() > 0 ? reportBO.getToBeConfirmCount() : 0);
        result.setToBeCommitCount(reportBO.getToBeCommitCount() > 0 ? reportBO.getToBeCommitCount() : 0);

        return result;
    }

    /**
     * 设置物流
     * @param tallyReportO
     * @param noticeVO
     * @return
     */
    @Override
    public MemberTallyReportBO setLogisticsTally(MemberTallyReportBO tallyReportO, OperateNoticeVO noticeVO) {
        if (!noticeVO.getDataSource().equals(OperateDataSourceEnum.LOGISTICS.getCode())) {
            return tallyReportO;
        }
        if (tallyReportO == null) {
            tallyReportO = new MemberTallyReportBO();
        }
        LogisticsTallyBO logisticsTallyBO = tallyReportO.getLogistics();
        if (logisticsTallyBO == null) {
            logisticsTallyBO = new LogisticsTallyBO();
        }
        // 更新数据
        LogisticsOperateTypeEnum typeEnum;
        if (noticeVO.getReduceCount() > 0) {
            typeEnum = LogisticsOperateTypeEnum.getEnum(noticeVO.getReduceOperateType());
            if (typeEnum != null) {
                switch (typeEnum) {
                    case TO_BE_COMMIT:
                        logisticsTallyBO.setToBeCommitCount(logisticsTallyBO.getToBeCommitCount() - noticeVO.getReduceCount());
                        break;
                    case TO_BE_CONFIRM:
                        logisticsTallyBO.setToBeConfirmCount(logisticsTallyBO.getToBeConfirmCount() - noticeVO.getReduceCount());
                        break;
                }
            }
        }
        if (noticeVO.getIncreaseCount() > 0) {
            typeEnum = LogisticsOperateTypeEnum.getEnum(noticeVO.getIncreaseOperateType());
            if (typeEnum != null) {
                switch (typeEnum) {
                    case TO_BE_COMMIT:
                        logisticsTallyBO.setToBeCommitCount(logisticsTallyBO.getToBeCommitCount() + noticeVO.getIncreaseCount());
                        break;
                    case TO_BE_CONFIRM:
                        logisticsTallyBO.setToBeConfirmCount(logisticsTallyBO.getToBeConfirmCount() + noticeVO.getIncreaseCount());
                        break;
                }
            }
        }
        tallyReportO.setLogistics(logisticsTallyBO);

        return tallyReportO;
    }

    /**
     * 统计计数
     * @param reportList
     * @return
     */
    @Override
    public List<MemberTallyReportDO> statisticsTally(List<MemberTallyReportDO> reportList) {
        if (reportList == null) {
            reportList = new ArrayList<>();
        }
        List<StatisticsCountBO> statisticsList = logisticsOrderDAO.getStatisticsCount();
        if (statisticsList == null) {
            logger.info("没有符合条件的物流计数统计数据");
            statisticsList = new ArrayList<>();
        }

        // 补全统计数据
        List<MemberTallyReportDO> finalReportList = reportList;
        statisticsList.stream().distinct().forEach(p -> {
            MemberTallyReportDO reportDO = finalReportList.stream()
                    .filter(o -> o.getMemberId().equals(p.getMemberId()) && o.getRoleId().equals(p.getRoleId()))
                    .findFirst().orElse(null);
            if (reportDO == null) {
                reportDO = new MemberTallyReportDO();
                reportDO.setMemberId(p.getMemberId());
                reportDO.setRoleId(p.getRoleId());
                finalReportList.add(reportDO);
            }
        });

        List<StatisticsCountBO> finalStatisticsList = statisticsList;
        finalReportList.forEach(p -> {
            // 如果报表数据为null，则实例化
            if (p.getTallyReport() == null) {
                p.setTallyReport(new MemberTallyReportBO());
            }
            LogisticsTallyBO tallyBO = new LogisticsTallyBO();
            // 待提交
            tallyBO.setToBeCommitCount(finalStatisticsList.stream()
                    .filter(o -> o.getMemberId().equals(p.getMemberId()) && o.getRoleId().equals(p.getRoleId())
                            && o.getStatusType().equals(LogisticsOrderStatusEnum.WAIT_SUBMIT.getCode()))
                    .mapToLong(StatisticsCountBO::getCount).sum());
            // 待确认
            tallyBO.setToBeConfirmCount(finalStatisticsList.stream()
                    .filter(o -> o.getMemberId().equals(p.getMemberId()) && o.getRoleId().equals(p.getRoleId())
                            && o.getStatusType().equals(LogisticsOrderStatusEnum.WAIT_CONFIRMED.getCode()))
                    .mapToLong(StatisticsCountBO::getCount).sum());
            p.getTallyReport().setLogistics(tallyBO);
        });

        return finalReportList;
    }
}
